/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rultax.blackice.physics.controller;

import java.util.List;
import org.jbox2d.common.Mat22;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;

/**
 * Tensor Damping controller is useful for some top down mechanics. Tensor is
 * fancy for Matrix in this case.
 *  
 * @author unknown contribution
 */
public class TensorDampingController extends MultiController {

    private Mat22 t;    
    private float maxTimeStep;
    
    /**
     * Creates a new instance of TensorDampingController.
     */
    public TensorDampingController(){
	super();
	t = new Mat22();
    }
    
    /**
     * Sets axis for damping
     * 
     * @param xDamping
     * @param yDamping
     */
    public void setAxisAligned(float xDamping, float yDamping){
	t.col1.x = -xDamping;
	t.col1.y = 0;
	t.col2.x = 0;
	t.col2.y = -yDamping;
	if(xDamping > 0 || yDamping > 0)
	    maxTimeStep = 1 / Math.max(xDamping, yDamping);
	else
	    maxTimeStep = 0;
    }
    
    @Override
    public void step(float dt) {
	if(dt <= Float.MIN_VALUE)
	    return;
	if(dt > maxTimeStep && maxTimeStep > 0)
	    dt = maxTimeStep;
	
	for (Body body : getBodies()) {
	    if(body.isAwake()){
		Vec2 damping = body.getWorldVector(Mat22.mul(t, body.getLocalVector(body.getLinearVelocity())));
		Vec2 linearVelocity = new Vec2(body.getLinearVelocity().x +  damping.x * dt, body.getLinearVelocity().y + damping.y * dt);
		body.setLinearVelocity(linearVelocity);
	    }	    
	}
    }
    
    /**
     * Creates a new TensorDampingController with the given bodies and matrix.
     * 
     * @param bodies
     * @param t
     * @return
     */
    public static TensorDampingController fromBodies(List<Body> bodies, Mat22 t){
	TensorDampingController c = new TensorDampingController();
	for (Body body : bodies) {
	    c.addBody(body);
	}
	if(t != null)
	    c.t.set(t);
	
	return c;
    }
}
